import axios from 'axios'
// 导入Toast提示消息组件
import { Toast } from 'vant'
// 导入vuex模块
import store from '../store/index'
// 导入路由模块
import router from '@/router/index.js'

// 按需导入换取 token 的 API
import { exchangeTokenAPI } from '@/api/userAPI.js'
console.log(store)
// 调用 axios.create() 方法，创建 axios 的实例对象
const request = axios.create({
  // 请求根路径
  baseURL: 'http://www.liulongbin.top:8000'
})
// 拦截器的挂载，一定要放到request实例创建之后
// 由于我们在项目中是基于request实例对象发起的请求，因此拦截器一定要挂载给request

// 添加请求拦截器
// 在请求拦截器的第一个function中，形参config就是每次请求时候的配置选项
request.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    // 展示loading效果
    Toast.loading({
      message: '努力奋斗中', // 提示信息
      duration: 0 // 防止自动关闭
    })

    // 从vuex中获取token的值
    const tokenStr = store.state.tokenInfo.token
    if (tokenStr) {
      config.headers.Authorization = 'Bearer ' + tokenStr
    } return config
  },
  function (error) {
    // 对请求错误做些什么
    // 隐藏loading效果
    Toast.clear()

    return Promise.reject(error)
  }
)
// 添加响应拦截器
// 响应拦截器
request.interceptors.response.use(
  response => {
    // 隐藏 loading 提示效果
    Toast.clear()
    return response
  },
  async error => {
    Toast.clear()

    // 1. 从 vuex 中获取 tokenInfo 对象，格式为： { token, refresh_token }
    const tokenInfo = store.state.tokenInfo
    // 2. 判断是否为 token 过期
    if (error.response && error.response.status === 401 && tokenInfo.refresh_token) {
      // token 过期
      console.log('token过期啦')

      // 3.1 TODO: 发起请求，根据 refresh_token 重新请求一个有效的新 token
      try {
        const { data: res } = await exchangeTokenAPI(tokenInfo.refresh_token)
        console.log(res)
        // 3.2 TODO: 更新 Store 中的 Token
        store.commit('updataTokenInfo', { token: res.data.token, refresh_token: tokenInfo.refresh_token })

        // 3.3 重新调用刚才“请求未遂”的接口
        // 3.3.1 如果在响应拦截器中 return 一个新的 Promise 异步请求，则会把这次请求的结果，当作上次请求的返回值
        return request(error.config)
      } catch {
        //  token 和 refresh_token 都失效了

        // 4.1 清空 vuex 和 localStorage
        store.commit('cleanState')
        // 4.2 强制跳转到登录页
        router.replace('/login?pre=' + router.currentRoute.fullPath)
      }
    }
    return Promise.reject(error)
  }
)
export default request
